package main

import (
	"fmt"
	"log"
	"time"
)

func zero() {
	t := time.NewTicker(time.Second * 1)
	c := 0
	for {
		select {
		case <-t.C:
			log.Printf("get ...%d\n", c)
			// 时间戳会直接触发
			t.Reset(0)
			time.Sleep(time.Millisecond * 500)
			c++
		}
	}
}

func longtime() {
	t := time.NewTicker(time.Millisecond * 200)
	for i := 0; i < 10; i++ {

		select {
		case <-t.C:
			go func() {
				fmt.Println("begin long task ...")
				time.Sleep(time.Millisecond * 400)
				fmt.Println("end long task ...")
			}()
			fmt.Println("receive timeout ")

		}
	}
}

// 如果超时是否，但是程序中重置是否会直接进入
// time.NewTicker 内部是一个channel
// 时间到了就会往里面推送, 只推送一次
// select {
//    case time.C <- time.After():
//   default
// }
func overtime() {
	t := time.NewTicker(time.Millisecond * 100)
	for i := 0; i < 10; i++ {
		now := time.Now()
		select {
		case <-t.C:
			// 休眠
			time.Sleep(400 * time.Millisecond)
			// 重置时间
			t.Reset(time.Millisecond * 500)

			log.Println(time.Since(now).Milliseconds())

			// output
			// 			2021/10/11 16:46:04 500
			// 2021/10/11 16:46:05 400
			// 2021/10/11 16:46:05 901
			// 2021/10/11 16:46:06 901
			// 2021/10/11 16:46:07 901
			// 2021/10/11 16:46:08 901
			// 2021/10/11 16:46:09 901
			// 2021/10/11 16:46:10 901
			// 2021/10/11 16:46:11 901
			// 2021/10/11 16:46:12 901
		}
	}
}

// 超时退出
func dobad(c chan bool) {
	// time.Sleep(time.Second * 1)
	time.Sleep(time.Millisecond * 100)
	select {
	case c <- true:
	default:
	}
}

func timeout() {
	c := make(chan bool, 0)
	go dobad(c)

	select {
	case <-c:
		fmt.Println("succeed")
	case <-time.After(time.Millisecond * 500):
		fmt.Println("timeout")
	}
}

func main() {
	overtime()
}
